package com.qf.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.cache.BlackListCache;
import com.qf.constans.ResultCode;
import com.qf.entity.CheckType;
import com.qf.entity.MyAuthUser;
import com.qf.entity.TAdminUser;
import com.qf.entity.TBlackList;
import com.qf.events.UpdateBlackEvent;
import com.qf.exceptions.AddDataException;
import com.qf.exceptions.MyBaseException;
import com.qf.exceptions.UpdateExceptions;
import com.qf.mapper.BlackListMapper;
import com.qf.utils.CheckPhone;
import jdk.management.resource.ResourceType;
import org.apache.ibatis.type.BaseTypeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.naming.Context;
import javax.sound.midi.Soundbank;
import java.util.List;
import java.util.stream.Collectors;

/*
杨威
2021/10/25
21:00
*/
@Service
@Transactional
public class BlackListServiceImpl implements com.qf.service.BlackListService {

    private BlackListMapper blackListMapper;
    private BlackListCache blackListCache;
    private ApplicationContext context;
    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    @Autowired
    public void setBlackListMapper(BlackListMapper blackListMapper){
        this.blackListMapper=blackListMapper;
    }
    @Autowired
    public void setBlackListCache(BlackListCache blackListCache) {
        this.blackListCache = blackListCache;
    }

    @Override
    public TBlackList findBlackById(Long id) {
        if(ObjectUtils.isEmpty(id)||id<=0){
            throw new MyBaseException("传递的id不合法", ResultCode.FAIL);
        }
        return blackListCache.getById(id);
    }

    @Override
    public void addBlack(TBlackList black) {
        System.out.println("black = " + black);
        if(!CheckPhone.isPhone(black.getMobile())){
            throw new AddDataException("手机号不符合规范",ResultCode.PHONE_NUM_ERROR);

        }
        blackListMapper.insertBlack(black);
        //发布一个更新事件
        context.publishEvent(new UpdateBlackEvent());
        System.err.println(Thread.currentThread().getName());
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public PageInfo<TBlackList> findAll(int pageNum, int pageSize) {
        long start = System.currentTimeMillis();
        PageHelper.startPage(pageNum, pageSize);//开始分页
//        List<TBlackList> blackList = blackListMapper.findAll();//查询数据
//        PageInfo<TBlackList> pageInfo = new PageInfo<>(blackList);//封装数据
        List<TBlackList> allData = blackListCache.getAllData();//从缓存中获取所有的数据
        //根据你传递的是第几页,要几条,裁剪集合
//        //List<TBlackList> subList = allData.subList((pageNum - 1) * pageSize, pageNum * pageSize);
//        List<TBlackList> subList = allData.stream()
//                .skip((pageNum - 1) * pageSize)//跳过指定的条数, 也就是设置偏移量
//                .limit(pageSize)//设置期望要的最多的数据量
//                .collect(Collectors.toList());//转存到一个新的集合中
        //上面的代码我们发现了一个问题,就是返回的数据中包含了其他人的数据
        //我们需要过滤,我们需要先判断出哪些数据是当前用户可以看到的,然后再起个
//        System.out.println(allData);
//        MyAuthUser authUser = (MyAuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        System.out.println(222);
////        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
////        Object user = ((ServletRequestAttributes) requestAttributes).getRequest().getSession().getAttribute("user");
//        //函数是一等公民
//        List<TBlackList> tBlackLists = allData.stream().filter(black -> {
//            //返回的是全局或者是创建者的数据,不能返回其他人的数据
//            return black.getOwntype() == 1 || black.getCreater() == authUser.getId() || authUser.getType() == 1;
//        }).collect(Collectors.toList());// 获取到符合当前用户能看到的所有的数据
//        //这是按照用户能看到的数据切割出来的分页数据
//        List<TBlackList> subList = tBlackLists.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());

        PageInfo<TBlackList> pageInfo = new PageInfo<>(allData);
//        pageInfo.setTotal(tBlackLists.size());//设置总条数
//        long end = System.currentTimeMillis();
//        System.err.println(end - start);
        return pageInfo;
    }

    @Override
    public void udpateBlack(TBlackList blackList) {
        //先对数据进行校验
        //要修改至少要两个内容，第一个主键 第二个要更新的内容
        if(blackList.isNull(CheckType.UPDATE)){
            throw new UpdateExceptions("您必须传递主键或者手机号", ResultCode.DATA_ISNULL);
        }
        //下来说明主键和手机号都正常传递了 执行SQL语句
        TBlackList blackById = blackListMapper.findBlackById(blackList.getId());
        if(blackList.getOwntype()!=1&&blackList.getCreater()!=blackById.getCreater()){
            //既不是管理员 又不是所有者 代表没有权限更新
            throw new UpdateExceptions("您没有权限修改当前数据",ResultCode.NO_PERMISSON);
        }
        //修改数据
        blackListMapper.update(blackList);
        //更新缓存
        context.publishEvent(new UpdateBlackEvent());
    }

    @Override
    public void deleteById(List<Integer> ids) {
        //根据id删除 只需传递id即可
        //如果传递的id中有的是自己创建的 有的不是自己创建的 怎么办
        //假如我们删除能删除的部分 返回不能删除的部分
        //如果当前用户是管理员 则可以直接删除所有数据
        //通过springMVC 获取user 相当于threadlocal
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        TAdminUser user = (TAdminUser)((ServletRequestAttributes) requestAttributes).getRequest().getSession().getAttribute("user");
        if(user.getType()==1){
            //说明是管理员 直接删除就行
            blackListMapper.deleteByIds(ids);
        }else {//说明不是管理员  只能删除自己创建的数据
            blackListMapper.deleteByIdsAndCreater(ids,user.getId());
        }
        //发布事件 刷新缓存
        context.publishEvent(new UpdateBlackEvent());
    }
}
